﻿using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Caching;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Volo.Abp.Localization;
using Volo.Abp.Users;
using static System.Net.Mime.MediaTypeNames;
using static Volo.Abp.Identity.Settings.IdentitySettingNames;
using Color = SixLabors.ImageSharp.Color;
using PointF = SixLabors.ImageSharp.PointF;

namespace Wuther.Infrastructure.SMS
{
    [RemoteService(IsEnabled = false)]
    public class SmsService : ApplicationService, ISmsService
    {
        private readonly UserManager<Volo.Abp.Identity.IdentityUser> UserManager;
        private readonly IRepository<IdentityUser> _userRepository;
        private readonly ILogger<SmsService> _logger;
        private readonly IConfiguration _configuration;
        private readonly IDistributedCache<string> _distributedCache;

        public SmsService(

            IdentityUserManager identityUserManager,
            UserManager<Volo.Abp.Identity.IdentityUser> userManager,
            IRepository<IdentityUser> userRepository,
            ILogger<SmsService> logger,
            IConfiguration configuration,
            IDistributedCache<string> distributedCache)
        {
            UserManager = userManager;
            _userRepository = userRepository;
            _logger = logger;
            _configuration = configuration;
            _distributedCache = distributedCache;
        }
        // 生成验证码
        public async Task<string> GetVerificationCodeAsync(string phone)
        {
            _logger.LogInformation("调用验证码接口");
            //var user = await _userRepository.GetAsync(c => c.PhoneNumber == phone);
            var code = "aaaa";
            var bb = _configuration;
            var cc = bb["GlobalConfiguration:BaseUrl"];
            var dd = _configuration.GetChildren();
            LocalizableString xx = new LocalizableString("Create");
            var yy = xx.Localize(StringLocalizerFactory);
            //Thread.Sleep(10000);

            Check.NotNull(code, nameof(code));

            return yy;
        }

        public async Task<CaptchaDto> GenerateCaptcha(GetCaptchaInput input)
        {
            string captchaCode = GenerateRandomCode(4);
            string captchaId = Guid.NewGuid().ToString();
            CaptchaDto captchaDto = new CaptchaDto();
            // 生成图片
            string base64Image;
            if(input.width == 0 || input.height == 0)
            {
                throw new UserFriendlyException("请输出宽高");
            }

            using (var image = GenerateCaptchaImage(captchaCode, input.width, input.height, 20))
            {
                base64Image = Convert.ToBase64String(image.ToArray());
            }
            
            // 存储到缓存（5分钟过期）
            _distributedCache.Set(captchaId, captchaCode, new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)
            });

            captchaDto.Id = captchaId;
            captchaDto.Img = $"data:image/png;base64,{base64Image}";
            return captchaDto;
        }

        private string GenerateRandomCode(int length)
        {
            var chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
            var rnd = new Random();
            return new string(Enumerable.Repeat(chars, length)
                .Select(s => s[rnd.Next(s.Length)]).ToArray());
        }

        private MemoryStream GenerateCaptchaImage(string captchaCode, int width, int height,int fontsize)
        {
            // 创建图片
            using var image = new Image<Rgba32>(width, height);

            // 设置背景颜色
            image.Mutate(ctx => ctx.BackgroundColor(SixLabors.ImageSharp.Color.White));

            // 加载字体（需确保系统有Arial字体，或使用自定义字体）
            FontCollection fonts = new();
            FontFamily fontFamily = fonts.AddSystemFonts().Families.First();
            SixLabors.Fonts.Font font = fontFamily.CreateFont(fontsize, FontStyle.Bold);

            // 绘制验证码文本
            var textOptions = new RichTextOptions(font)
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Origin = new SixLabors.ImageSharp.PointF(width / 2f, height / 2f)
            };

            image.Mutate(ctx => ctx.DrawText(
                textOptions,
                captchaCode,
                Brushes.Solid(Color.Black),
                Pens.Solid(Color.Gray, 1)
            ));

            // 添加干扰线
            var rnd = new Random();
            for (int i = 0; i < 3; i++)
            {
                var pen = Pens.Solid(Color.Gray, 1);
                image.Mutate(ctx => ctx.DrawLine(
                    pen,
                    new PointF(rnd.Next(0, width), rnd.Next(0, height)),
                    new PointF(rnd.Next(0, width), rnd.Next(0, height))
                ));
            }

            // 添加噪点
            image.Mutate(ctx =>
            {
                //for (int i = 0; i < 100; i++)
                //{
                //    ctx.SetPixel(
                //        new SixLabors.ImageSharp.Point(rnd.Next(0, width), rnd.Next(0, height)),
                //        new Rgba32(
                //            (byte)rnd.Next(0, 255),
                //            (byte)rnd.Next(0, 255),
                //            (byte)rnd.Next(0, 255)
                //        )
                //    );
                //}
                for (int i = 0; i < 100; i++)
                {
                    int x = rnd.Next(0, image.Width);
                    int y = rnd.Next(0, image.Height);
                    image[x, y] = new Rgba32(
                        (byte)rnd.Next(0, 255),
                        (byte)rnd.Next(0, 255),
                        (byte)rnd.Next(0, 255)
                    );
                }
            });
            // 保存到内存流
            var memStream = new MemoryStream();
            image.SaveAsPng(memStream);
            memStream.Position = 0;

            return memStream;
        }
    }
}